#ifndef _EB0_WORLD_H_
#define _EB0_WORLD_H_

#include <EB0/Prereq.h>
#include <EB0/States/GameState.h>
#include <Box2D/Box2D.h>
#include <map>
#include <set>
#include <string>

namespace EB0
{
namespace States
{
	class World : public GameState
	{
	public:
		World();
		~World();

	public:
		bool attachEntity(char* refname, Entities::Entity* entity); // returns false if refname is in use
		Entities::Entity* fetchEntity(char* refname);
		bool removeEntity(char* refname); // returns false if refname not found
		bool removeEntity(Entities::Entity* entity); // returns false if entity not found
		void removeAllEntities();
		int getNumEntities() const;

		b2World* getWorld() const;
		Window::Layer* getWorldLayer() const;

	protected:
		void loadWorld(Window::RenderWindow* window = 0);
		void createWorldScene(Window::RenderWindow* window = 0);
		void destroyWorldScene(Window::RenderWindow* window = 0);
		void unloadWorld(Window::RenderWindow* window = 0);

		void updateWorld(Window::RenderWindow* window = 0, float dt = 0.0f);

		virtual void onKeyRelease(Window::RenderWindow* window, const sf::Event::KeyEvent& key);
		virtual void onLoseFocus(Window::RenderWindow* window);

	private:
		typedef std::map<std::string, Entities::Entity*> EntityMap;
		typedef std::set<Entities::Entity*> EntitySet;

		EntityMap mEntities;
		b2World* mWorld;
		Window::Layer* mWorldLayer;

		bool mDirtyEntityMap;

		mutable sf::Mutex mMutex;
		static const int32 mPhysicsIterations = 10;
	};
} // namespace States
}

#endif // _EB0_WORLD_H_